//
// Copyright (c) 2008-2011, Kenneth Bell
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections.Generic;

namespace DiscUtils.Diagnostics
{
    /// <summary>
    /// The report generated by replaying file system actions from a checkpoint.
    /// </summary>
    /// <remarks>This report contains detailed tracing information.</remarks>
    public sealed class ReplayReport
    {
        private Exception _failureException;
        private Exception _replayException;
        private List<StreamTraceRecord> _globalTraceReport;
        private List<StreamTraceRecord> _traceReport;
        private int _replayBufferSize;
        private int _eventsReplayed;
        private long _eventsBeforeLockdown;
        private string _replayPreVerificationReport;
        private bool _failedVerifyOnReplay;
        private string _replayVerificationReport;
        private string _lastCheckpointReport;

        internal ReplayReport(
            Exception failureEx,
            Exception replayEx,
            TracingStream globalTraceStream,
            TracingStream traceStream,
            int replayBufferSize,
            int eventsReplayed,
            long eventsBeforeLockdown,
            string replayPreVerificationReport,
            bool failedVerifyOnReplay,
            string replayVerificationReport,
            string lastCheckpointReport)
        {
            _failureException = failureEx;
            _replayException = replayEx;
            _globalTraceReport = new List<StreamTraceRecord>(globalTraceStream.Log);
            _traceReport = new List<StreamTraceRecord>(traceStream.Log);
            _replayBufferSize = replayBufferSize;
            _eventsReplayed = eventsReplayed;
            _eventsBeforeLockdown = eventsBeforeLockdown;
            _replayPreVerificationReport = replayPreVerificationReport;
            _failedVerifyOnReplay = failedVerifyOnReplay;
            _replayVerificationReport = replayVerificationReport;
            _lastCheckpointReport = lastCheckpointReport;
        }


        /// <summary>
        /// The exception (if any) that caused the file system verification check to fail.
        /// </summary>
        public Exception VerificationFailureException
        {
            get
            {
                return _failureException;
            }
        }

        /// <summary>
        /// The exception (if any) that cause the full replay to fail.
        /// </summary>
        public Exception ReplayException
        {
            get
            {
                return _replayException;
            }
        }

        /// <summary>
        /// The stream activities traced whilst replaying the file system action that broke the file system.
        /// </summary>
        public IEnumerable<StreamTraceRecord> InterCheckpointStreamTraceLog
        {
            get
            {
                return _globalTraceReport;
            }
        }

        /// <summary>
        /// The stream activities traced whilst replaying the file system action that broke the file system.
        /// </summary>
        public IEnumerable<StreamTraceRecord> ReplayStreamTraceLog
        {
            get
            {
                return _traceReport;
            }
        }

        /// <summary>
        /// The number of replay events available to replay.
        /// </summary>
        public int ReplayEventsAvailable
        {
            get
            {
                return _replayBufferSize;
            }
        }

        /// <summary>
        /// The number of replay events successfully replayed.
        /// </summary>
        public int ReplayEventsProcessed
        {
            get
            {
                return _eventsReplayed;
            }
        }

        /// <summary>
        /// Gets whether file system corruption was detected whilst replaying events.
        /// </summary>
        public bool ReplayFailedVerification
        {
            get
            {
                return _failedVerifyOnReplay;
            }
        }

        /// <summary>
        /// Gets the file system verification report generated at the last checkpoint.
        /// </summary>
        public string LastCheckpointReport
        {
            get
            {
                return _lastCheckpointReport;
            }
        }

        /// <summary>
        /// Gets the file system verification report generated whilst just before replaying the file system action that failed.
        /// </summary>
        public string ReplayPreVerificationReport
        {
            get
            {
                return _replayPreVerificationReport;
            }
        }

        /// <summary>
        /// Gets the file system verification report generated whilst replaying the file system action that failed.
        /// </summary>
        public string ReplayVerificationReport
        {
            get
            {
                return _replayVerificationReport;
            }
        }

        /// <summary>
        /// The total number of events processed (ignoring events run during replay).
        /// </summary>
        public long TotalEventsProcessed
        {
            get
            {
                return _eventsBeforeLockdown;
            }
        }
    }
}
